#include "bank.h"
#include <math.h>

using namespace std;
bool Bank::ifCustomerArrive() const
{
    // 设置概率模型
    //平均每小时(3600秒)到达客户数
    int num=12;
    /*”计算当前这1秒，有客户来的概率，并放大3600倍,即
    probability=概率*3600=num/(1*60*60)*3600=num
    因为这个概率算下来非常小,即使用double来存储，计算机也会四舍五入成0。
    所以必须放大，放大系数设置成3600，是为了方便。
    本模型认为1秒钟已经是非常短的时间，故认为同时到来多个客户的情况可以忽略，这也是模型缺陷*/
    double probability=num;

    // 建立随机试验
    //在[0,3600]之间随意以均匀概率取一个点(随机采样)
    double random=(   (double)rand() / (RAND_MAX)   )*3600;

    // 判断随机试验结果并返回
    if(random<=probability)//若随机采样点位于[0,probability]区间，则认为有顾客到来
    {
        // cout<<"========================================================================================"<<endl;
        return true;
    }   
    else //若随机采样点位于[probability,1]区间,则认为没有顾客到来。
        return false;

}
bool Bank::ifWindowsIdly() const
{
    // 设置概率模型
    int ablity=10;//单个窗口服务能力---平均每小时(3600秒)服务客户数。
    int ablitys=ablity*windowNums;//所有窗口累计服务能力。
    /*计算当前这1秒，银行所有窗口能够输出1个服务能力的概率，并放大3600倍。
    即probability=概率*3600=ablitys/(1*60*60)*3600=ablitys
    因为这个概率算下来非常小,即使用double来存储，计算机也会四舍五入成0。
    所以必须放大，放大系数设置成3600，是为了方便
    本模型认为1秒钟已经是非常短的时间，故认为同时可以输出多个服务能力(同时多个窗口空闲)的情况可以忽略，这也是模型缺陷
    */
    double probability=ablitys;

    //建立随机试验
    double random=(   (double)rand() / (RAND_MAX)   )*3600;//在[0,3600]之间随意以均匀概率采样(随机采样)


    // 判断随机试验结果并返回
    if(random<=(probability)) //若随机采样点位于[0，probability]区间，则认为有顾客到来
        return true;
    else //若随机采样点位于[probability,1]区间,则认为没有顾客到来。
        return false;
}

void Bank::simulation(int rounds)
{
    int currCus=0;
    int lastCus=0;
    for(;currTime<=workTime;currTime++)
    {
        
        if(ifCustomerArrive()&&waitingQueue.size()<1000)
        {
            /*设置等候队列上限，如果队列太长，则禁止顾客进入，但是
            这样势必会增加后面时间段中，顾客到来的概率增大，此模型未考虑这一因素*/
            waitingQueue.push(Customer(currTime));
        }
        if(ifWindowsIdly()&&!waitingQueue.empty())
        {
            /*若等候队列为空，说明此刻供不应求，出现这种情况肯定会影响
            窗口空闲概率分布，例如：长时间的供不应求情况出现时候，势
            必会导致很多窗口闲置，势必会造成后面时间段中窗口闲置的概率
            增加，此模型未考虑这一因素*/ 
            servedQueue.push_back
            (
                waitingQueue.front().set_getServeTime(currTime).set_WaitingTime()
            );
            waitingQueue.pop();
        }
        // 如果有客户到来,则输出当前状态信息
        currCus=waitingQueue.size()+servedQueue.size();
        if(currCus>lastCus)
        {
            cout<<"当前时间："<<currTime<<endl;
            cout<<"当前到店客户数:"<<waitingQueue.size()+servedQueue.size()<<endl;
            cout<<"当前排队人数:"<<waitingQueue.size()<<endl;
            cout<<"完成服务人数:"<<servedQueue.size()<<endl;
            cout<<"\n";  
            lastCus=currCus;
        }
        
    }
}




